<?php
namespace app\api\controller;
use think\Controller;
use think\Debug;
class Api extends Controller
{
    protected $appid = 1; 
    private $logs_id;
    private $logs_tb;
    private $secret = 'ydj@e3DBSm92p%#Fcd6nsjp;t3r7dgfS#'; //秘钥？
    protected $input_data = ''; 
    protected $suc_code = '';
    protected $err_code = '';
    protected $c = '';
    protected $a = '';
    protected function _initialize()
    {
        Debug::remark('begin');
        header('access-Control-Allow-Origin:*');
        $this->suc_code = 20000;
        $this->err_code = 20001;
        //当前访问的控制器名称
        $this->c = request()->controller();
        //当前访问的方法名称
        $this->a = request()->action();

        $method = 'api/'.$this->c.'/'.$this->a;
        
        //请求的数据
        $this->input_data = $data = $input_array = input('post.');

        // $this->resErr($input_array['work_place_lat']);
        unset($this->input_data['nonceStr']);
        //datetime
        $input_time = $input_array['timestamp'];

        


        //日志记录
        // $this->logs_tb = $this->logs_tb();
        // $this->logs_id = $this->input($method,$input_array,$input_time);
        //时间验证
        // if($input_time > (time() + 60) )
        // {
        //     $this->resErr('非法请求2');
        // }

        //验证签名
        if( ! $this->verifySign($input_array) )
        {
            //签名不通过
            $result = array(
                'code' => $this->err_code,
                'data' => '签名不正确'
            );
            $this->res($result);
        }

        //验证身份是否有效


    }
    protected function setMaps($map,$fields,$type = 'EQ')
    {
        return setMaps($map,$this->post($fields),$fields,$type);
    }
    // 统一获取传入的post值
    protected function post($fields)
    {
        if ( !isset($this->input_data[$fields]) ) return '';
        return $this->input_data[$fields];
    }
    //公用输出错误的方法
    protected function resErr($msg)
    {
        $data = array(
            'code' => $this->err_code,
            'data' => $msg
        );
        $this->res( $data );
    }
    //公用输出正确的方法
    protected function resSuc($msg)
    {
        Debug::remark('end');
        $data = array(
            'code' => $this->suc_code,
            'data' => $msg,
            'runtime' => Debug::getRangeTime('begin','end').'s',
            'user' => $this->user
        );
        $this->res( $data );
    }

    //输出方法
    //把结果记录到日志中，并用base64编码然后输出
    protected function res($arr=array())
    {
        // $this->output($this->logs_id,$arr);
        // var_dump($this->logs_id);die;
        echo json_encode($arr);
        die;
    }

    //把收到的请求写入日志
    protected function input($method,$input,$input_time)
    {
        if(db($this->logs_tb)->where(['sign'=>$input['sign']])->find()) $this->resErr('非法请求1');
        return db($this->logs_tb)->insertGetId(array(
            'appid'=>$this->appid,
            'method'=>$method,
            'ip'=>request()->ip(),
            'input'=>is_array($input)?addslashes(json_encode($input,JSON_UNESCAPED_UNICODE)):$input,
            'input_time'=>date('Y-m-d H:i:s',$input_time),
            'sign'=>$input['sign']
        ));
        
        
    }

    //把接口的输出结果写入日志
    protected function output($logs_id,$output)
    {
        $logs_id = intval($logs_id);
        if(!$logs_id) return NULL;
        return db($this->logs_tb)->where('id='.$logs_id)->update(array(
        'output'=>addslashes(is_array($output)?json_encode($output,JSON_UNESCAPED_UNICODE):$output),
        'output_time'=>date('Y-m-d H:i:s',$_SERVER['REQUEST_TIME']),
        ));
    }

    // 建立日志表
    protected function logs_tb()
    {
        $db = config('database.database');
        $tb = 'logs_api_'.date('Ym');
        $tableName = config('database.prefix').$tb;

        $isTable = db()->query('SHOW TABLES LIKE '."'".$tableName."'");
        if(!$isTable)
        {

            $sql = "CREATE TABLE IF NOT EXISTS `".$db."`.`".$tableName."` (
            `id` int NOT NULL AUTO_INCREMENT,
            `appid` tinyint(3) UNSIGNED NOT NULL COMMENT '操作来源 1=后端 2=软件端',
            `method` varchar(255) DEFAULT NULL,
            `ip` varchar(100) DEFAULT NULL,
            `input` text DEFAULT NULL,
            `input_time` datetime DEFAULT NULL,
            `output` text DEFAULT NULL,
            `output_time` datetime DEFAULT NULL,
            `sign` CHAR(32) NOT NULL,
            PRIMARY KEY (`id`),
            UNIQUE (`sign`),
            KEY `method` (`method`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='接口日志表';";

            $yn = db()->query($sql);
        }
        return $tb;
    }



    //验证签名是否合法
    private function verifySign($data) 
    {
        // 验证参数中是否有签名
        if (!isset($data['sign']) || !$data['sign']) {
            return false;
            die();
        }
        if (!isset($data['timestamp']) || !$data['timestamp']) {
            return false;
            die();
        }
        // 验证请求， 10分钟失效
        if (time() - $data['timestamp'] > 600) {
            return false;
            die();
        }
        $sign = $data['sign'];

        unset($data['sign']);
        // unset($data['timestamp']);
        // unset($data['token']);
        ksort($data);

        $params = '';
        foreach( $data as $k=>$v ) $params.=$k.'='.$v.'&';

        $sign2 = md5($params .'key='. $this->secret);
        $signErr = $params .'key='. $this->secret;
        // $sign2 = $params .'key='. $this->secret;

        if ($sign == $sign2) 
        {
            return true;
        } 
        else 
        {
            $this->resErr($signErr);

        }
    }


    /*
        后台操作记录日志的统一方法
    */
    protected function actLogs($cate,$description)
    {
        $data = array(
            'cate' => $this->appid,
            'logs_type' => $cate, //分类 1=常规 2=配置 3=资金
            'description' => $description,
            'act_uid' => $this->user['id'],
            'act_ip' => request()->ip(),
            'act_time' => time(),
            'api_logs_tb' => $this->logs_tb,
            'api_logs_id' => $this->logs_id,
        );

        db('LogsActivity')->insert($data);
    }


}


